package oneD.models;

import oneD.fem.Constraint;
import oneD.fem.Force;
import oneD.fem.Node;
import oneD.fem.method.ArcLengthControl;
import oneD.fem.structure.PrestressTruss;
import oneD.fem.structure.Structure;
import oneD.fem.visualize.TrussVisualizer;
import inf.jlinalg.ArrayVector;
import inf.jlinalg.BLAM;
import inf.jlinalg.IVector;
import inf.v3d.view.Viewer;

public class NonlinearSmallTetraeder extends ModelViewer {

	public PrestressTruss createStructure() {
		PrestressTruss struct = new PrestressTruss();
		double lb = 15.0;
		double r = 457.2 / 2000;
		double t = 10.0 / 1000;
		double a = Math.PI * (Math.pow(r, 2) - Math.pow(r - t, 2));
		double e = 2.1e11;
		Constraint c1 = new Constraint(false, false, false);
		Constraint c2 = new Constraint(true, true, false);
		Force f = new Force(0, -20e3, -100e3);
		f.scale(1);
		// f.scale(5264); //->get many iterations
		// create nodes
		Node n1 = struct.addNode(0.0, 0.0, lb * Math.sqrt(2.0 / 3.0));
		Node n2 = struct.addNode(0.0, lb / Math.sqrt(3), 0);
		Node n3 = struct.addNode(-lb / 2, -lb / Math.sqrt(12.0), 0);
		Node n4 = struct.addNode(lb / 2, -lb / Math.sqrt(12.0), 0);
		// apply BCs
		n1.setForce(f);
		n2.setConstraint(c1);
		n3.setConstraint(c1);
		n4.setConstraint(c2);
		// create elements
		struct.addElement(1, e, a, 0, 0, 1);
		struct.addElement(1, e, a, 0, 0, 2);
		struct.addElement(1, e, a, 0, 0, 3);
		struct.addElement(1, e, a, 0, 1, 2);
		struct.addElement(1, e, a, 0, 2, 3);
		struct.addElement(1, e, a, 0, 3, 1);
		// return the new structure
		return struct;
	}

	public static void visualizeStructure(Structure struct) {
		Viewer viewer = new Viewer();
		TrussVisualizer viz = new TrussVisualizer(struct, viewer);

		// set scaling factors
		double d_max = viz.automaticScale();
		// viz.setAreaScale(10);
		// viz.setConstraintSymbolScale(0.5);
		// viz.setForceSymbolScale(0.25e-4);
		// viz.setForceSymbolRadius(0.1);
		// viz.setDisplacementScale(0.75e4);
		// viz.setLinePlotScale(-0.3e-4);
		// draw
		viz.drawElements();
		viz.drawConstraints();
		viz.drawForces();
		viz.postAutomaticScale(d_max);
		// viz.drawDisplacements();
		viz.drawDisplacedStructure();
		// viz.drawElementForces();
		// show viewer
		viewer.setVisible(true);
	}

	@Override
	public void initializeVisualizer(Structure struct) {
		this.view_ = new Viewer();
		viz_ = new TrussVisualizer(struct, this.view_);
	}

	@Override
	protected void performLinearModalAnalysis(Structure struct) {
		/*
		 * perform linear modal analysis
		 */
		System.out
				.println("This functionality is not supported for this model");
	}

	@Override
	protected void performNonlinearInstabilityAnalysisUsingDirectComputation(
			Structure struct) {
		/*
		 * instability analysis using direct computation
		 */
		double lambda = -0.1;
		IVector phi = new ArrayVector(struct.enumerateDOFs());
		BLAM.fill(phi, 0.1);
		IVector u = struct.createZeroU();
		struct.directLoadControlInstabilityComputation(u, lambda, phi);
	}
	
	@Override
	protected void performLoadDisplacementAnalysisUsingArcLength(
			Structure struct) {
		struct.enumerateDOFs();
		IVector u = struct.createZeroU();
		double lambda = 0.0;
		ArcLengthControl m = new ArcLengthControl(struct);
		// m.setConstraintType("load control");
		// m.setConstraintType("displacement control");
		m.setU0(u);
		m.setLambda0(lambda);
		m.setConstraintType("sphere");
		m.setParameterS(0.01);
		m.setNumStep(100);
		m.setPsi(1.0);
		// m.run();
		// m.print();
		oneD.fem.method.Plot1D p = m.plot();
		p.setVisible(true);
	}
	
	public static void main(String[] args) {
		NonlinearSmallTetraeder model = new NonlinearSmallTetraeder();
		model.processUserInput();

		// PrestressTruss struct = createStructure();

		// linear solution
		// struct.solve(false, null);

		/*
		 * nonlinear static deformation solution
		 */
		// struct.iterateNewtonRaphson(struct.createZeroU());
		// struct.printResults();
		// System.out.println();
		// visualizeStructure(struct);

		/*
		 * instability analysis using direct computation
		 */
		// IVector u = struct.createZeroU();
		// double lambda = -0.1;
		// IVector phi = new ArrayVector(struct.enumerateDOFs());
		// BLAM.fill(phi, 0.1);
		// struct.directLoadControlInstabilityComputation(u, lambda, phi);

		/*
		 * instability analysis using second order theory
		 */
		// struct.solve();
		// IVector u = struct.getU();
		// IVector lambda = null;
		// struct.secondOrderLoadControlInstabilityComputation(3, u, lambda);
	}

}
